﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using EuroManager.Domain.Simulator.Engine;
using EuroManager.Domain.Simulator.Helpers;
using EuroManager.Domain.Simulator.World;

namespace EuroManager.Domain.Simulator
{
    public class Randomizer : IRandomizer
    {
        private Random random = new Random();

        public Vector2D AutoBallKickVelocity(float minLength, float maxLength)
        {
            return Vector(minLength, maxLength);
        }

        public float PlayerAIDecisionDelaySalt(float delay)
        {
            return Number(-delay / 4, delay / 4);
        }

        public bool ShouldPassBall(float chance)
        {
            return random.NextDouble() < chance;
        }

        public IPlayer PlayerToPassBallTo(IEnumerable<IPlayer> players, float[] chances)
        {
            return Choose(players, chances);
        }

        public float PlayerReceivePassSpeed(float minSpeed, float maxSpeed)
        {
            return Number(minSpeed, maxSpeed);
        }

        public bool ShouldShoot(float chance)
        {
            return random.NextDouble() < chance;
        }

        private float Number(float minValue, float maxValue)
        {
            float difference = maxValue - minValue;
            return (float)(minValue + random.NextDouble() * difference);
        }

        private Vector2D Vector(float minLength, float maxLength)
        {
            Vector2D direction = new Vector2D(Number(-1.0f, 1.0f), Number(-1.0f, 1.0f));
            float length = Number(minLength, maxLength);

            return direction.Normalized() * length;
        }

        private T Choose<T>(IEnumerable<T> items, float[] chances)
        {
            float total = chances.Sum();
            float choice = (float)random.NextDouble() / total;
            float current = 0;
            int index = 0;

            foreach (T item in items)
            {
                current += chances[index];

                if (choice < current)
                {
                    return item;
                }

                index++;
            }

            return items.Last();
        }
    }
}
